# -*- coding: utf-8 -*-

# Author : 'hxc'

# Time: 2018/12/17 10:42 AM

# File_name: 'combine.py'

"""
Describe: this is a demo!
"""
import time
import os
import re
from ConsultAPI.ProposalAPI import Proposal
import codecs

from lxml import etree



start = time.time()

class Find_Difference(object):
    """
    解析html文件进行对比差异整合内容。
    """

    def __init__(self, xml_file, html_source_path, name_list, uuid, pool):

        self.xml_file = xml_file
        self.html_source_path = html_source_path
        self.report_name_list = name_list
        self.uuid = uuid
        self.pool = pool

    # def __get_htmlfile_path(self):
    #     """
    #     获取所有可能html文件的绝对路径.
    #     :return:
    #     """
    #     # html_file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.html_source_path)
    #     # print('>>>' * 50)
    #     # print('HTML源文件的路径：', html_file_path)
    #     #存放所有可能文件的路径
    #     html_file_list = []
    #     for name in self.report_name_list:
    #         html_file_list.append(self.html_source_path + name)
    #     return html_file_list


    def __do_zero_file(self,):
        """
        如果数据库里返回的是0个报告，则返回固定的html.
        :return:
        """
        # #解析模块的名字
        # module_name = self.html_source_path.split('/')
        # print("用户访问的模块名字为：", module_name[-2])
        # with open('./ConsultAPI/pattern_html/' + module_name[-2]+ '/pattern.html' , 'r', encoding='utf-8') as f,\
        #     open('./ConsultAPI/final_combine/final.html', 'w', encoding='utf-8') as f_w:
        #
        #     context = f.read()
        #     f_w.write(context)
        # 解析模块的名字
        module_name_list = self.xml_file.split('/')
        print(module_name_list)
        temp_module_name = module_name_list[-1]
        module_name = temp_module_name[:-13]
        print("用户访问的模块名字为：", module_name)
        with open('./pattern_html/' + module_name + '/pattern.html', 'r', encoding='utf-8') as f, \
                open('./final_combine/final.html', 'w', encoding='utf-8') as f_w:
            context = f.read()
            f_w.write(context)

    def __do_one_file(self, html_file_list):
        """
        如果数据库里返回是1个报告，则返回该报告的html.
        :return:
        """
        f_w = open('./ConsultAPI/final_combine/final.html', 'w', encoding='utf-8')
        with open( html_file_list[0], 'r', encoding='utf-8') as f:
            context = f.read()
            f_w.write(context)
            f_w.close()
    def __read_html_file(self, each_htmlfile_path):
        """
        读取html文件
        :return: 返回一个tree的对象
        """
        f = codecs.open(each_htmlfile_path, 'r', encoding='utf-8')
        context = f.read()
        f.close()
        tree = etree.HTML(context)
        return tree

    def __get_h1(self, each_htmlfile_path):
        """
        利用xpath获取h1内容。
        :return: 返回h1内容
        """
        h1_list = []
        tree = self.__read_html_file(each_htmlfile_path)
        element = tree.xpath('//h1')
        for child in element:
            h1_list.append(child.text)
        return h1_list

    def __get_h1_relation(self, html_file_list):
        """
        获取各个报告的关系
        :param html_file:
        :return:
        """
        h1_context_list = []
        for each_htmlfile_path in html_file_list:
            h1_context_list.append(self.__get_h1(each_htmlfile_path))
        return dict(zip(self.report_name_list, h1_context_list))

    def __do_process_html_relation(self, mydict):
        """
        寻找html的关系,把相同标题框架的html放在一起，为了好比较。
        :return:
        """
        unique = {}
        newDict = {}
        for k, v in mydict.items():
            v = tuple(v)
            newDict[k] = v
        for k, v in newDict.items():
            if v not in unique:

                unique[v] = [k]
            else:
                unique[v].append(k)
        return unique

    def __do_remove(self,sentence):
        """
        去掉重复的字符
        :return:
        """
        sentence_ = ""
        for i in sentence:
            if i not in sentence_:
                sentence_ += i
        return sentence_

    def __do_one_sentence(self,new_sentence0, new_sentence):
        """
        找到要合的句子
        :param new_sentence0:
        :param new_sentence:
        :return:
        """
        l0 =''
        l = ''
        for x in new_sentence0:
            if x not in new_sentence:
                l0 += x
        for y in new_sentence:
            if y not in new_sentence0:
                l += y
        l0 = self.__do_remove(l0)
        l = self.__do_remove(l)
        return (l0, l)


    def __do_context_diff(self,sentence0,sentence):
        """
        处理一个多选问题，进行不相同的部分整合。
        :return:
        """
        print(sentence0)
        print(sentence)
        if 'style'in sentence0 or'style'in sentence :
            #进行表格内容融合
            pattern1 = re.compile(r'<br>.\..*</strong><strong')
            sentence_context0 = re.findall(pattern1, sentence0)
            sentence_context = re.findall(pattern1, sentence)
            if sentence_context0 == [] :
                pattern2 = re.compile(r'<br>.\..*</strong>')
                sentence_context0 = re.findall(pattern2, sentence0)
            if sentence_context == []:
                pattern2 = re.compile(r'<br>.\..*</strong>')
                sentence_context = re.findall(pattern2, sentence)
            temp_sentence_context0 = sentence_context0[0]
            temp_sentence_context = sentence_context[0]
            # print(temp_sentence_context0.split('<br>'))
            # print(temp_sentence_context.split('<br>'))
            # print(set(temp_sentence_context0.split('<br>') + temp_sentence_context.split('<br>')))
            new_str = '<br>'
            temp_l = []
            for i in set(temp_sentence_context0.split('<br>') + temp_sentence_context.split('<br>')):
                i = i.replace('0.', '')
                i = i.replace('1.', '')
                i = i.replace('2.', '')
                i = i.replace('3.', '')
                i = i.replace('4.', '')
                i = i.replace('5.', '')
                i = i.replace('6.', '')
                i = i.replace('7.', '')
                i = i.replace('8.', '')
                i = i.replace('9.', '')
                i = i.replace('</strong><strong', '')
                i = i.replace('</strong>', '')
                temp_l.append(i)
            print("表格小标题的set:",set(temp_l))
            for id, j in enumerate(set(temp_l)):
                if id > 0:
                    new_str = new_str + str(id) + '.' + j + '<br>'
            final_str = new_str[0:-4] + '</strong><strong'
            return sentence0.replace(temp_sentence_context0, final_str)
        else:
            new_sentence0 = sentence0.split('strong>')
            new_sentence = sentence.split('strong>')
            if new_sentence0[0] == new_sentence[0]:
                #进行融合成一句话
                print('6666')
                l0, l = self.__do_one_sentence(new_sentence0, new_sentence)
                l0 = l0.replace('</', '')
                l0 = l0.replace('。', '')
                l0 = l0.replace('，', '')
                l0 = l0.replace('？', '')
                l0 = l0.replace('！', '')
                l = l.replace('</', '')
                l = l.replace('。', '')
                l = l.replace('，', '')
                l = l.replace('？', '')
                l = l.replace('！', '')
                one_setence = l0 + '、' + l
                new_sentence_result = re.sub(l0, one_setence, sentence0)
                return new_sentence_result
            else:
                #进行拼接
                if '<br>'  in sentence0 :
                    new_sentence_result = sentence + '\n' + sentence0
                    return new_sentence_result
                else:
                    return sentence0

    def __do_compare(self, context0, context):
        """
        对比2个内容，返回融合的内容
        :param context0:
        :param context:
        :return:
        """
        str = ' '
        #先进行判断context的标题在context0里有没有，如果没有直接拼接处理，如果有先拿到该标题下内容
        t0 = re.findall(r'<h2>.*?</h2>', context0)
        t = re.findall(r'<h2>.*?</h2>', context)

        if t0 == [] or t ==[]:
            t0 = re.findall(r'<h1>.*?</h1>', context0)
            t = re.findall(r'<h1>.*?</h1>', context0)
        print(t0)
        print(t)

        if t[0] in t0:
            # 相同的标题进行do_compare
            context0_list = context0.split(t[0])
            context_list = context.split(t[0])
            temp_context0 = context_list[0]+ t[0] + context0_list[-1]
            new_context0 = temp_context0.split('\n')
            new_context = context.split('\n')

            for i in range(min(len(new_context0), len(new_context))):

                if new_context0[i] == new_context[i]:
                    str += new_context0[i] + '\n'
                else:
                    # print(i)
                    # print(new_context0[i])
                    # print(new_context[i])
                    diff_context = self.__do_context_diff(new_context0[i], new_context[i])

                    str +=  diff_context + '\n'

        else:
            context0_list = context0.split(t0[0])
            context_list = context.split(t[0])
            temp_context0 = t0[0] + context0_list[-1]
            temp_context = t[0] + context_list[-1]
            str += context0_list[0] + temp_context0 + temp_context
        return str

    def __do_first_context(self, context):
        """
        拿到第一块内容。
        :param context0:
        :return:
        """
        pattern1 = re.compile(r'<h6.*<h1>二', re.S)
        temp_context = re.findall(pattern1, context)
        if temp_context == []:
            pattern2 = re.compile(r'<h6.*', re.S)
            temp_context = re.findall(pattern2, context)
            if temp_context == []:
                pattern2 = re.compile(r'<h1.*<h1>', re.S)
                temp_context = re.findall(pattern2, context)
        new_context = temp_context[0]
        new_context = new_context.replace('<h1>二', '')
        return new_context



    def __do_process_h2_title(self, temp_h2, combine_context):
        """
        处理最终的报告合成h2标题的排序
        :param temp_h2:
        :param combine_context:
        :return:
        """

        number = len(temp_h2)
        number_dict = {'0': '（一）', '1': '（二）', '2': '（三）', '3': '（四）', '4': '（五）', '5': '（六）', '6': '（七）', '7': '（八）', '8': '（九）', '9': '（十）', '10': '（十一）', '11': '（十二）', '12': '（十三）', '13': '（十四）', '14': '（十五）', '15': '（十六）', '16': '（十七）', '17': '（十八）', '18': '（十九）', '19': '（二十）', '20': '（二十一）'}
        for id in range(number):
            title_number_pattern = re.compile(r'<h2>（.*）')
            new_title = '<h2>' + number_dict[str(id)]
            new = re.sub(title_number_pattern, new_title, temp_h2[id])
            print('55555', new)
            temp_final_string = combine_context.replace(temp_h2[id], new)
            combine_context = temp_final_string

        return temp_final_string

    def __do_single_list(self, unique):
        """
        处理单个lis中的报告,而且还list中报告必须大于等于2,不然不会来到这一步
        :param unique:
        :return:
        """
        #获取unique的key元组
        for keys, values in unique.items():
            if len(keys) == 1:
                #直接融合
                print('>>>>>>>>>>> 开始！！！key元祖为1的合并 <<<<<<<<<<<<<<<<<<<')
                f0 = codecs.open(self.html_source_path + values[0], 'r', encoding='utf-8')
                context0 = f0.read()
                f0.close()
                i = 1
                while i < len(values):
                    print(i)
                    #循环对比每个文件内容
                    f = codecs.open(self.html_source_path + values[i], 'r', encoding='utf-8')
                    context = f.read()
                    f.close()
                    temp_context = self.__do_compare(context0, context)
                    context0 = temp_context + '\n'
                    i += 1
                #此时contex0即为最后要写入的内容
                return context0

            elif len(keys)>1:
                #直接融合第一个内容
                print('>>>>>>>>>>> 开始！！！key元祖大于1的合并 <<<<<<<<<<<<<<<<<<<')
                f0 = codecs.open(self.html_source_path + values[0], 'r', encoding='utf-8')
                context0 = f0.read()
                f0.close()
                #获取第一块内容
                first_context0 = self.__do_first_context(context0)

                old_first_context0 = first_context0
                i = 1
                while i < len(values):
                    f = codecs.open(self.html_source_path + values[i], 'r', encoding='utf-8')
                    context = f.read()
                    f.close()
                    first_context = self.__do_first_context(context)
                    print('######', first_context0)
                    print('%%%%%%', first_context)
                    temp_context = self.__do_compare(first_context0, first_context)
                    print('&&&&&&', temp_context)
                    first_context0 = temp_context + '\n'
                    i += 1
                #此时first_context0为要写入的内容，所以要与context0进行repalce
                # new_context =  context0.replace(old_first_context0, first_context0)
                # return new_context
                # h2标题排序
                pattern_h2_title = re.compile(r'<h2>.*?</h2>')
                temp_h2 = re.findall(pattern_h2_title, first_context0)
                if temp_h2 == [] or '<h2>（一） 结论</h2>' in temp_h2 or '<h2>（二） 特别提示</h2>' in temp_h2 or '<h2>（三） 特别提示</h2>' in temp_h2:
                    # return f0
                    new_context = context0.replace(old_first_context0, first_context0)
                    return new_context
                temp_combine_context_new = self.__do_process_h2_title(temp_h2, first_context0)
                # 此时first_context0为要写入的内容，所以要与context0进行repalce
                new_context = context0.replace(old_first_context0, temp_combine_context_new)
                return new_context
            else:
                #如果没有标题，只返回第一个html。
                print(">>>>>>>>>>>>>>注意！！！这是没有标题的html合并 <<<<<<<<<<<<<<<<<<<<")
                f0 = codecs.open(self.html_source_path + values[0], 'r', encoding='utf-8')
                context0 = f0.read()
                f0.close()
                return context0

    def __split_unique(self, unique):
        """
        把unique拆分成单个的dict然后放在一个list中。
        :param unique:
        :return:
        """
        unique_list = []
        for i in range(len(unique)-1):
            for keys, values in unique.items():
                unique_list.append({keys: values})
            return unique_list

    def __do_max_length_context(self, context_list):
        """
        输出list中长度最大的string
        :param context_list:
        :return:
        """
        f0 = context_list[0]
        for i in range(1, len(context_list)):
            if len(context_list[i]) > len(f0):
               f0 = context_list[i]
            else:
                f0 = f0
        return f0

    def __do_combine(self,new_context0, new_context):
        """
        处理第一块不同的内容
        :return:
        """
        #判断h1标题是否相同
        pattern = re.compile(r'<h1>.*?</h1>', re.S)
        titil0 = re.findall(pattern, new_context0)
        titil = re.findall(pattern, new_context)

        if titil0 == titil:
            #继续判断
            if '<h2>' in new_context0 or '<h2>' in new_context:

                pattern_h2 = re.compile(r'<h2>.\.*</h2>', re.S)
                titil0_h2 = re.findall(pattern_h2, new_context0)
                titil_h2 = re.findall(pattern_h2, new_context)
                if titil0_h2 == titil_h2:
                    #直接处理融合
                    return self.__do_compare(new_context0, new_context)
                else:
                    #需要拼接
                    pattern_h2_context = re.compile(r'<h2>（.*', re.S)
                    context0_h2 = re.findall(pattern_h2_context, new_context0)
                    context_h2 = re.findall(pattern_h2_context, new_context)
                    new = context0_h2[0] + '\n' + context_h2[0]
                    combine_context_new = new_context0.replace(context0_h2[0], new)
                    return combine_context_new
            else:
                #直接处理融合
                return self.__do_compare(new_context0, new_context)

        else:
            #直接拼接
            pattern1 = re.compile(titil0[0] + '.*', re.S)
            pattern2 = re.compile(titil[0] + '.*', re.S)
            c0 = re.findall(pattern1, new_context0)
            c = re.findall(pattern2, new_context)
            new = c0[0] + '\n' + c[0]
            combine_context_new = new_context0.replace(c0[0], new)
            return combine_context_new



    def __do_first_context_combine(self, context_list):
        """
        处理第一块内容，并返回融合结果
        :param context_list:
        :return:
        """
        f0 = self.__do_first_context(context_list[0])
        i = 1
        while i < len(context_list):
            first_context = self.__do_first_context(context_list[i])

            new_context = self.__do_combine(f0, first_context)
            f0 = new_context
            i += 1
        # h2排序
        pattern_h2_title = re.compile(r'<h2>.*?</h2>')
        temp_h2 = re.findall(pattern_h2_title, f0)
        # pattern_h1_title = re.compile(r'<h1>.*?</h1>')
        # temp_h1 = re.findall(pattern_h1_title, f0)
        # print('77777', temp_h1)
        # if temp_h2 == [] or len(temp_h1) > 1:
        if temp_h2 == [] or '<h2>（一） 结论</h2>' in temp_h2 or '<h2>（二） 特别提示</h2>' in temp_h2 or '<h2>（三） 特别提示</h2>' in temp_h2:
            return f0
        print('676767', temp_h2)
        temp_combine_context_new = self.__do_process_h2_title(temp_h2, f0)
        print('666666', temp_combine_context_new)
        return temp_combine_context_new


    def __do_multi_list(self, unique):
        """
        处理多个list的报告。
        :return:
        """
        print(">>>>>>>>>>>> 进行多个list的报告合并 <<<<<<<<<<<<<")
        context_list = []
        #拆分unique组成单个list报告
        unique_list = self.__split_unique(unique)
        print('拆分后的unique_list', unique_list)
        #处理单个list的报告
        for i in unique_list:
            context = self.__do_single_list(i)
            context_list.append(context)
        print("最后合并文件的大小：", len(context_list))
        #处理多个单个list报告的结果
        #获取最长报告为模版
        pattern_context = self.__do_max_length_context(context_list)
        #处理每个第一块内容，返回第一块内容合并的结果
        old_first_context = self.__do_first_context(pattern_context)
        all_first_context = self.__do_first_context_combine(context_list)
        final_context = pattern_context.replace(old_first_context, all_first_context)
        return final_context

    def __do_process_h1_title(self,temp_title, temp_final_string):
        """
        处理最终的报告h1标题排序
        :return: 返回最终报告的string
        """
        new_list =[]

        for i in temp_title:
            if i not in new_list:
                new_list.append(i)
            else:
                temp_final_string= re.sub(i[::-1],'',temp_final_string[::-1],1)
                temp_final_string = temp_final_string[::-1]

        temp_title_new = list(set(temp_title))
        number = len(new_list)
        print('@@@@@@@@@@', temp_title_new)
        number_dict = {'0': '一', '1': '二', '2': '三', '3': '四', '4': '五', '5': '六', '6': '七', '7': '八', '8': '九', '9': '十',  '10': '十一',  '11': '十二' }
        for id in range(number):
            title_number_pattern = re.compile(r'<h1>.、')
            new_title = '<h1>' + number_dict[str(id)] + '、'
            new = re.sub(title_number_pattern, new_title, new_list[id])
            new_list.append(new)
            temp_final_string = temp_final_string.replace(new_list[id], new)
        return temp_final_string

    def __do_multi_report_combine(self, html_file_list):
        """
        如果数据库里返回多个报告，则进行融合
        :return:
        """
        #大致获取各个报告的关系，得到unique
        temp_unique = self.__get_h1_relation(html_file_list)
        print('temp_unique的类型是', type(temp_unique))
        print('temp_unique的长度为：',len(temp_unique))
        print('temp_unique:')
        print(temp_unique)
        unique = self.__do_process_html_relation(temp_unique)
        print('unique的长度为：', len(unique))
        print('unique:')
        print(unique)
        #如果unique长度是1
        if len(unique) == 1:
            #1.处理一个list下的报告
            context = self.__do_single_list(unique)
            f_w = codecs.open('./ConsultAPI/final_combine/final.html', 'w', encoding='utf-8')
            f_w.write(context)
            f_w.close()
            print('>>>>>>>>>>> 结束！！！单个list下报告的合并 <<<<<<<<<<<<<<<<<<<')
        #如果unique长度大于1
        else:
            #2.处理多个list下的报告
            context = self.__do_multi_list(unique)
            # 对h1进行排序
            pattern_h1_title = re.compile(r'<h1>.*?</h1>')
            temp_title = re.findall(pattern_h1_title, context)
            print('9999',temp_title)
            final_string = self.__do_process_h1_title(temp_title, context)
            f_w = codecs.open('./ConsultAPI/final_combine/final.html', 'w', encoding='utf-8')
            f_w.write(final_string)
            f_w.close()
            print('>>>>>>>>>>> 结束！！！多个list下报告的合并 <<<<<<<<<<<<<<<<<<<')

    def final_combine(self):
        """
        对外接口
        :return:
        """
        #获取每个报告的绝对路径
        # html_file_list = self.__get_htmlfile_path()
        proposal = Proposal(self.uuid, self.pool)
        name_list, html_file_list = proposal.run()
        print(len(html_file_list))

        #判断html_file_list的大小 如果是1则直接写入final.html文件；如果大于1则一个一个对比融合。如果是0，怎返回固定final.html
        if len(html_file_list) == 0:
            #1.写固定的final.html

            self.__do_zero_file()
            return '返回固定final_html成功!'

        elif len(html_file_list) == 1:
            #2.把这个html写入final.html

            self.__do_one_file(html_file_list)
            return '返回单报告成功!'
        else:
            #3.循环对比融合，把融合结果与下一个再进行对比融合

            self.__do_multi_report_combine(html_file_list)
            return '返回多个报告合并成功!'

if __name__ == '__main__':


    report_name_list =['7cfb4b408e48511a57f0c0c6cfff67cb5ddb0e1a932515998458ba8d40641d17.html',
     '5e68f7a500d6f7403e07d7fd70701299f28420d800f23f7bf8f5f8aae4f6ec3b.html',
     '27dd4b8987b444cc7b3cbc731a78ac08c9d6a35aa0d420b706e8107908e2afca.html',
     '0792d95332a6901a431a145c3da1db7cff3371149c1726f633df35c07ac16c96.html',
     'aa3934ea5b5dd3914b9ff1d82cb6ad9d61d50388d777a149158022b4a15429cb.html',
     'd98e80e44af451fb5d098cee625d129e7b3b750a3d6be1697d712cb1a2653819.html']

    # combiner = Find_Difference('./data/离婚后小孩问题_tree_new.xml',  './data/离婚后小孩问题/', report_name_list)
    combiner = Find_Difference('./data/能不能离婚_tree_new.xml',  './data/能不能离婚/', report_name_list)

    print(combiner.final_combine())